package com.ruoyi.warning.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.warning.domain.entity.*;
import com.ruoyi.warning.mapper.WarningSyslogConfigurationMapper;
import com.ruoyi.warning.service.*;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * <p>
 * 告警配置表 服务实现类
 * </p>
 *
 * @author chenhc
 * @since 2025-07-31
 */
@Service
public class WarningSyslogConfigurationServiceImpl extends ServiceImpl<WarningSyslogConfigurationMapper, WarningSyslogConfiguration> implements IWarningSyslogConfigurationService {

    @Resource
    private WarningSyslogConfigurationMapper warningSyslogConfigurationMapper;
    @Resource
    private IEventService eventService;
    @Resource
    private IDevicesService devicesService;
    @Resource
    private IPropertyService propertyService;
    @Resource
    private IEventDetailService eventDetailService;
    @Resource
    private IDisposeService disposeService;
    @Resource
    private IConfigurationService configurationService;
    @Override
    public void refresh() throws Exception {
        //获取五分钟内的日志并筛选掉正常日志和重复的
        //获取当前时间和五分钟
        Date now = new Date();
        Date fiveMinuteAgo = DateUtils.addMinutes(now, -60);
        //获取五分钟内的去重日志
        List<Syslog> list = warningSyslogConfigurationMapper.getFiveMinuteLog(now,fiveMinuteAgo);

        //将deviceid转换为不会重复的字符串
        List<String> deviceIdList = list.stream()
                .map(Syslog::getDeviceId)
                .map(String::valueOf)
                .distinct()
                .toList();
        //        Map<String, Syslog> syslogMap = new HashMap<>();
//        //将日志放入map中
//        for(Syslog syslog:list){
//            syslogMap.put(syslog.getDeviceId().toString(),syslog);
//        }
        System.out.println(list);
        System.out.println("================");
        Set<WarningSyslogConfiguration> allConfigurations = new HashSet<>();
        //根据deviceid查询告警配置
        for(String deviceId:deviceIdList){
            //根据deviceid查询告警配置
            List<WarningSyslogConfiguration> warningSyslogConfigurationList = this.list(new LambdaQueryWrapper<WarningSyslogConfiguration>()
                    .like(WarningSyslogConfiguration::getDeviceId, deviceId));
            //将告警配置放入map中
            if(ObjectUtils.isEmpty(warningSyslogConfigurationList)){
//                deviceIdList.remove(deviceId);
                //去除list中所有等于deviceId的对象
                list.removeIf(syslog -> deviceId.equals(syslog.getDeviceId().toString()));
            }else {
                allConfigurations.addAll(warningSyslogConfigurationList);
            }
        }
        //此时map中是所有涉及device的告警配置
        System.out.println(allConfigurations);
        // 遍历 Syslog 列表
        for (Syslog syslog : list) {
            String syslogDeviceId = syslog.getDeviceId().toString();
            for (WarningSyslogConfiguration config : allConfigurations) {
                if (config.getDeviceId().contains(syslogDeviceId)
                        &&config.getLogLevel().contains(syslog.getLevel())
                        ) {
                    //将配置中的关键字按逗号分割成数组
                    String[] keywordArray = config.getKeyword().split(",");
                    for (String keyword : keywordArray) {
                        if (syslog.getMsg().contains(keyword)) {
                            //确定符合条件，先记录事件
                            this.recordEvent(syslog,config,fiveMinuteAgo);
//                            this.sendWarning(syslog,config);
                            break;
                        }
                    }
                }
            }
        }
    }

    private void recordEvent(Syslog syslog, WarningSyslogConfiguration config,Date fiveMinuteAgo) throws Exception {
        //先找到是否已存在该事件
        LambdaQueryWrapper wrapper = new QueryWrapper<Event>().lambda()
                .eq(Event::getDeviceId,syslog.getDeviceId())
                .eq(Event::getWarningTime,syslog.getTimestamp())
                .eq(Event::getTitle,config.getSysname())
                .ge(Event::getUpdateTime,fiveMinuteAgo)
                .orderByDesc(Event::getUpdateTime)
                .last("limit 1");
        Event event = eventService.getOne(wrapper);
        EventDetail eventDetail = new EventDetail();
        if (!ObjectUtils.isEmpty(event)) {
            Dispose dispose =
                    disposeService.getOne(
                            new QueryWrapper<Dispose>().lambda()
                                    .eq(Dispose::getEventId, event.getId()));
            eventDetail = eventDetailService.getOne(
                    new QueryWrapper<EventDetail>().lambda()
                            .eq(EventDetail::getEventId, event.getId())
                            .orderByDesc(EventDetail::getCreateTime)
                            .last("limit 1"));
            // 如果有就更新
            if (!ObjectUtils.isEmpty(dispose)) {
                if (dispose.getDisposeStatus().equals("已忽略")) {
                    event.setRemark("已忽略");
                    eventDetail.setIsWarning("0");
                    eventDetail.setEventId(event.getId());
                    eventDetail.setMsg(event.getMsg());
                    eventDetail.setWarningTime(syslog.getTimestamp());
                    eventDetail.setTitle(event.getTitle());
                    return;
                } else {
                    event.setRemark("正在告警中");
                    eventDetail.setIsWarning("1");
                }
            } else {
                event.setRemark("正在告警中");
                eventDetail.setIsWarning("1");
            }

        } else {
            Device device = devicesService.getById(syslog.getDeviceId());
            // 没有就新增，重新初始化 event 对象
            Property property = propertyService.getOne(
                    new QueryWrapper<Property>().lambda()
                            .eq(Property::getHostname, device.getHostname()));
            event = new Event();
            event.setDeviceId(device.getDeviceId());
            event.setHostName(device.getHostname());
            if(com.baomidou.mybatisplus.core.toolkit.ObjectUtils.isNotEmpty(property)){
                event.setDeviceName(property.getName());
            }else {
                event.setDeviceName(device.getSysName());
            }
            event.setWarningTime(syslog.getTimestamp());
            event.setMsg(syslog.getMsg());
            event.setRemark("正在告警中");
            event.setTitle(config.getSysname());
            eventDetail.setIsWarning("0");
        }
        //修改或新增事件
        eventService.saveOrUpdate(event);
        System.out.println("第一次保存");
        System.out.println("===========");
        //找到刚才的事件
        event = eventService.getOne(wrapper);
        //添加事件详情
        eventDetail.setEventId(event.getId());
        eventDetail.setMsg(event.getMsg());
        eventDetail.setWarningTime(syslog.getTimestamp());
        eventDetail.setTitle(event.getTitle());
        eventDetail.setRemark("正在告警中");
        eventDetailService.saveOrUpdate(eventDetail);
        Configuration configuration = new Configuration();
        BeanUtils.copyProperties(config,configuration);
        event = configurationService.warningSend(event,eventDetail,configuration);
//        eventService.saveOrUpdate(event);
//        eventDetail.setRemark(event.getRemark());
//        eventDetailService.saveOrUpdate(eventDetail);
    }
}
